package pers.vic.sso.server.storage.model;

import pers.vic.boot.util.JsonUtil;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 描述:
 *     本地数据的缓存
 * @author Vic.xu
 * @date 2021-11-02 14:36
 */
public class LocalDataCache implements Serializable {

    private static final long serialVersionUID = -1881655835885172174L;

    /**
     * 保存所有数据
     */
    private static final Map<String, Map<String, LocalData>> CACHE_BUCKET = new ConcurrentHashMap<>();


    /**
     * 缓存
     * @param cacheName cacheName
     * @param key key
     * @param data data
     */
    public static void cache(String cacheName, String key, LocalData data){
        Map<String, LocalData> map = getMap(cacheName);
        map.put(key, data);
    }

    /**
     * 获得一个cacheName对应的整个map
     * @param cacheName
     * @return map
     */
    private static Map<String, LocalData> getMap(String cacheName){
        Map<String, LocalData> dataMap = CACHE_BUCKET.get(cacheName);
        if (dataMap == null) {
            dataMap =  new ConcurrentHashMap<>();
            CACHE_BUCKET.put(cacheName, dataMap);
        }
        return dataMap;
    }

    /**
     * 获得某个cacheName中某个Key对应的数据
     * @param cacheName cacheName
     * @param key key
     * @return data
     */
    public static LocalData get(String cacheName, String key){
        return getMap(cacheName).get(key);
    }

    /**
     * 删除某个cacheName中的某个key
     * @param cacheName  cacheName
     * @param key key
     * @return 被删除的data
     */
    public static LocalData remove(String cacheName, String key){
        return getMap(cacheName).remove(key);
    }

    /**
     * 刷新某个key的过期时间
     * @param cacheName cacheName
     * @param key key
     * @return 刷新的data
     */
    public static LocalData refresh(String cacheName, String key){
        LocalData data = getMap(cacheName).get(key);
        if (data != null) {
            data.refresh();
        }
        return data;
    }

    /**
     * 检测缓存是否过期，过期则删除;
     */
    public static void checkAndExpire(){
        CACHE_BUCKET.forEach((name, map)->{
            map.forEach((k,v)->{
                if (v.isExpire()) {
                    map.remove(k);
                }
            });
            if (map.isEmpty()) {
                CACHE_BUCKET.remove(name);
            }
        });
    }

    public static void printCache(){
        System.out.println("LocalDataCache#################################################start");
        CACHE_BUCKET.forEach((name, map)->{
            System.out.println("------------------------");
            System.out.println(name + ": " + map.size());
            JsonUtil.printJson(map);
            System.out.println("|||||||||||||||||||||||||");
        });

        System.out.println("LocalDataCache#################################################end");
    }

}
